InitialContext initCtx = new InitialContext(); Context envCtx = (Context) initCtx.lookup("java:comp/env"); javax.jcr.Repository repository = (javax.jcr.Repository) envCtx.lookup("jcr/myrepo");
This page is a placeholder to document various aspects of using ModeShape, including deployment, configuration, and general usage. These topics will be reorganized.
ModeShape can pretty easily be deployed to servlet containers and application servers. There are two options:
Use the RepositoryFactory mechanism and specify in the URL the location of the repository configuration
Use a JNDI ObjectFactory to automatically create the javax.jcr.Repository instance and register it in JNDI, then access it in JNDI
One of the more popular ways to find a Repository instance is to use JNDI, though this only works in environments like web servers or application servers that contain a JNDI implementation. It also assumes that a Repository instance has already been registered in JNDI; how this is done is specific to the environment.
When ModeShape is installed and deployed into a JBoss AS7 installation, the ModeShape will automatically register each deployed repository in JNDI, which by default is at "/jcr/repositoryName" (where "repositoryName" is the name of the repository). Simply use the JBoss AS7 administration tools to configure and deploy as many repositories as needed, including customizing the JNDI location of each repository.
Then in your application, simply look up each Repository instance from JNDI:
InitialContext initCtx = new InitialContext(); Context envCtx = (Context) initCtx.lookup("java:comp/env"); javax.jcr.Repository repository = (javax.jcr.Repository) envCtx.lookup("jcr/myrepo");
There are several ways of deploying ModeShape and registering the Repository instances in JNDI. One is to simply create a web application that sets up ModeShape and its repositories, where each repository configuration file specifies the location in JNDI where ModeShape should register that repository.
However, many servlet containers and application servers provide a way to configure a JNDI ObjectFactory that will create the necessary objects as soon as a client uses JNDI to look up the object at a particular location; after that, the objects will be registered in JNDI and found. ModeShape provides an ObjectFactory implementation, so simply configure your server to use it, and deploy your applications to look in JNDI for ModeShape's Repository instances.
Although each server configures the ObjectFactory instances differently, they all basically define the following:
The name of the ObjectFactory implementation class. For ModeShape, this is "org.modeshape.jcr.JndiRepositoryFactory".
Custom properties. For ModeShape, there are two for each repository:
The "configFile" property that specifies the location for the JSON repository configuration file.
The "repositoryName" property that specifies the name of the repository. This value must match the name in the configuration file.
Note that that although the "repositoryName" can be found in the configuration file, specifying it does allow the factory to quickly find the named repository if it were already deployed, without having to read the configuration file.
Here's an example of a fragment of the conf/context.xml for Tomcat that registers ModeShape's Repositories implementation in JNDI at "jcr", and deploys two repositories using a different JSON configuration file for each one:
<Resource name="jcr/myrepo" auth="Container" factory="org.modeshape.jcr.JndiRepositoryFactory" repositoryName="My Repository" configFile="/resource/path/to/repository-config.json" />
Simply provide a similar fragment for each repository that is to be registered in JNDI.
Then in your application, simply look up the Repository instance from the correct JNDI location:
InitialContext initCtx = new InitialContext(); Context envCtx = (Context) initCtx.lookup("java:comp/env"); javax.jcr.Repository repository = (javax.jcr.Repository) envCtx.lookup("jcr/myrepo");
This us approach requires using a ModeShape-specific extension to the standard JCR API. The org.modeshape.jcr.api.Repositories interface represents a collection of named repository instances. The ModeShape engine implements this interface, so you can register the ModeShape engine in JNDI at a particular location, and have your application use JNDI to find the Repositories instance and get the Repository instance by name.
You might be wondering why you'd want to use this mechanism, since it relies upon non-standard APIs. Well, this mechanism was designed for one particular use case that can't really use any of the other (preferred) mechanisms: a web application that works with any available repository, but needs to know which repositories are available.
Consider a web application that serves as a web-based front end for a bunch of repositories. Typically, the repository name is part of the URL, and so this application works regardless of which or how many repositories are deployed as long as the client includes the name of a running repository in the URL. But how does the client know which repository is available? Normally, the client would just ask the web service for the list of repositories. But that's not possible using any of the aforementioned mechanisms, and why we created the Repositories interface:
public interface Repositories { /** * Get the names of the available repositories. * * @return the immutable set of repository names provided by this server; never null */ Set<String> getRepositoryNames(); /** * Return the JCR Repository with the supplied name. * * @param repositoryName the name of the repository to return; may not be null * @return the repository with the given name; never null * @throws javax.jcr.RepositoryException if no repository exists with the given name or there is an error communicating with * the repository */ javax.jcr.Repository getRepository( String repositoryName ) throws javax.jcr.RepositoryException; }
As you can see, these two methods allow the application to discover which repositories are available and to obtain any of the named repositories. And this will work even when repositories are deployed or undeployed.
When ModeShape is installed and deployed into a JBoss AS7 installation, the ModeShape's Repositories implementation is registered in JNDI at "/jcr". Simply use the JBoss AS7 administration tools to configure and deploy repositories.
Then in your application, simply look up the Repositories instance from JNDI, and get the names of the available repositories and/or get a Repository with a particular name.
InitialContext initCtx = new InitialContext(); Context envCtx = (Context) initCtx.lookup("java:comp/env"); org.modeshape.jcr.api.Repositories repositories = (org.modeshape.jcr.api.Repositories) envCtx.lookup("jcr"); // Get the names of the available repositories ... Set<String> repoNames = repositories.getRepositoryNames(); // Get the repository given a name ... String repoName = //... javax.jcr.Repository repo = repositories.getRepository(repoName);
There are several ways of deploying ModeShape and registering the Repositories instance in JNDI. One is to simply create a web application that sets up ModeShape and registers it in JNDI; as long as this web app is deployed first, your other web applications will be able to find it.
However, many servlet containers and application servers provide a way to configure a JNDI ObjectFactory that will create the necessary objects as soon as a client uses JNDI to look up the object at a particular location. ModeShape provides an ObjectFactory implementation, so simply configure your server to use it, and deploy your applications to look in JNDI for ModeShape's Repositories instance.
Although each server configures the ObjectFactory instances differently, they all basically define the following:
The name of the ObjectFactory implementation class. For ModeShape, this is "org.modeshape.jcr.JndiRepositoryFactory".
Custom properties. For ModeShape, this is the "configFiles" property with a value that is a comma-separated list of locations for each of the JSON repository configuration files that should be deployed.
Note that "configFiles" is plural. Be sure to use this property name; don't use "configFile" unless you want to register the repository instance.
Here's an example of a fragment of the conf/context.xml for Tomcat that registers ModeShape's Repositories implementation in JNDI at "jcr", and deploys two repositories using a different JSON configuration file for each one:
<Resource name="jcr" auth="Container" factory="org.modeshape.jcr.JndiRepositoryFactory" configFiles="/resource/path/to/first/repository-config.json, /resource/path/to/second/repository-config.json" />
Then in your application, simply look up the Repositories instance from JNDI, and get the names of the available repositories and/or get a Repository with a particular name.
InitialContext initCtx = new InitialContext(); Context envCtx = (Context) initCtx.lookup("java:comp/env"); org.modeshape.jcr.api.Repositories repositories = (org.modeshape.jcr.api.Repositories) envCtx.lookup("jcr"); // Get the names of the available repositories ... Set<String> repoNames = repositories.getRepositoryNames(); // Get the repository given a name ... String repoName = //... javax.jcr.Repository repo = repositories.getRepository(repoName);
Unregistering the Repositories object from JNDI will shut down the ModeShape engine, and the JndiRepositoryFactory will recreate it if needed.